package services;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import play.Logger;
import models.Setting;
import models.SettingType;

public class SettingService {
	
	private static SettingService service;
	
	private SettingService() {
	}
	
	public static SettingService getService() {
		if (service == null) {
			service = new SettingService();
			// Persist default settings in database
			service.synchronizeSettings();
		}
		return service;
	}
	
	public Setting getSetting(String name) {
		Setting setting = Setting.find.where().eq("name", name).findUnique();
		if (setting == null) {
			setting = new Setting("");
		}
		return setting;
	}
	
	public boolean settingExists(String name) {
		return Setting.find.where().eq("name", name).findUnique() != null;
	}
	
	public void synchronizeSettings() {
		File templateFile = new File("resources/templates/settings.txt");
		if (templateFile.exists()) {
			try {
				FileReader reader = new FileReader(templateFile);
				BufferedReader br = new BufferedReader(reader);
				String line, name, value, description;
				String[] settingTokens;
				SettingType type;
				Setting setting;
				while ((line = br.readLine()) != null) {
					try {
						line = line.trim();
						if (line.startsWith("#")) {
							continue;
						}
						settingTokens = line.replaceAll("\t{2,}", "\t").split("\t", 4);
						if (settingTokens.length >= 3) {
							name = settingTokens[0].trim();
							if (!settingExists(name)) {
								type = SettingType.valueOf(settingTokens[1].trim());
								value = settingTokens[2].trim();
								description = settingTokens.length > 3 ? settingTokens[3].trim() : "";
								setting = new Setting(name);
								switch (type) {
									case Boolean:
										if (!value.isEmpty()) {
											setting.setBooleanValue(Boolean.parseBoolean(value));
										} else {
											setting.setBooleanValue(false);
										}
										break;
									case Float:
										if (!value.isEmpty()) {
											setting.setFloatValue(Float.parseFloat(value));
										} else {
											setting.setFloatValue(0);
										}
										break;
									case Integer:
										if (!value.isEmpty()) {
											setting.setIntegerValue(Integer.parseInt(value));
										} else {
											setting.setIntegerValue(0);
										}
										break;
									case String:
									default:
										setting.setStringValue(value);
										break;
								}
								setting.setDescription(description);
								setting.save();
							}
						}
					} catch (Exception e) {
						Logger.warn("Unable to parse setting line " + line, e);
					}
				}
				br.close();
				reader.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}
